﻿/*
* m328pSerie.c
*
* Created: 05-12-2011 15:43:56
*  Author: Vitor Veiga
*/

#include "m328pSerie.h"




/************************************************************************/
/* Serial Communication for atmega328p - 8bit, No parity and 1 stop-bit	*/ 
/************************************************************************/
void m328pSerialConfig(uint8_t _baudRate)
{
	UBRR0 = _baudRate;
	
	// receive and transmit enable
	UCSR0B = ( (1 << RXEN0) | (1 << TXEN0) );
	
	// 8 bit
	UCSR0C = ( (1 << UCSZ00) | (1 << UCSZ01) );
}





/************************************************************************/
/* Send a Char thought serial communication								*/
/************************************************************************/
void m328pSendChar(char data)
{
	while ( !(UCSR0A & (1 << UDRE0)) );
	UDR0 = data;
	
	while ( !(UCSR0A & (1 << TXC0)) );
	UCSR0A |= (1 << TXC0);
}





/************************************************************************/
/* Send String thought serial communication                             */
/************************************************************************/
void m328pSendString(char* str)
{
	int index = 0;
	
	// iterate char array
	while (str[index]){
		m328pSendChar(str[index++]);
	}
}





/************************************************************************/
/* Read Char of serial Buffer                                           */
/************************************************************************/
char m328pReceiveChar(void) { return UDR0; }





/************************************************************************/
/* Check if there is any char to read                                   */
/************************************************************************/
_Bool m328pIsCharAvailable(void) { return (UCSR0A & (1 << RXC0)); }





/************************************************************************/
/* Get an Input Command by User                                         */
/************************************************************************/
char* m328pGetSerialCommand(void)
{
	static uint8_t index = 0;
	static char cmd[CMD_MAX_LENGTH];
	static _Bool isCmdTooLong = false;
	
	/*
	 *	Process cmd
	 */
	if( m328pIsCharAvailable() )
	{
		
		/*
		 *	Check for [Enter Key]
		 */
		if( (cmd[index] = m328pReceiveChar()) == '\n')
		{
			#if DEBUG
				if(!isCmdTooLong){
					m328pSendString("[Length] ");
					m328pSendString(itoa(index,SERIAL_BUFFER,10));
					m328pSendChar('\n');
				}
			#endif
			
			// terminate cmd: replace '\n' by '\0'
			cmd[index] = '\0';
			index = 0;
			
			if(isCmdTooLong){
				isCmdTooLong = false;
				
				#if DEBUG
					m328pSendString("[Error] cmd too long\n\n");
				#endif
				
				return NULL;
			} 
			
			return cmd;
		} 
		
		/*
		 *	Check for max cmd size
		 */
		if(index < (CMD_MAX_LENGTH - 1) ){
			
			// next char
			index++;	
		} else {
			
			// too long
			isCmdTooLong = true;
		}
	}
	
	return NULL;
}